#include "tcpserver.h"

TcpServer::TcpServer(QObject *parent, QTcpServer* server, int port  )
    : QObject{parent}, tcpServer(server), m_port(port)
{
    connect(tcpServer, &QTcpServer::newConnection, this, &TcpServer::do_newConnection);
}

void TcpServer::start()
{
    if (!tcpServer->listen(QHostAddress::Any, m_port)) {
        // 发送信号
        emit listenFailed(tcpServer->errorString());
        qDebug() << "Server could not start:" << tcpServer->errorString();
    } else {
        // 发送信号
        emit listenSuccess(tcpServer->serverPort());
        qDebug() << "Server started on port" << tcpServer->serverPort();
    }
}

void TcpServer::stop()
{
    // 1. 停止接受新连接
    tcpServer->pauseAccepting();
    // 2. 断开所有客户端连接
    // 3. 关闭服务器
    tcpServer->close();
    // 关闭时检查错误
    // if (!tcpServer->close()) {
    //     qWarning() << "Failed to close server properly:"
    //                << tcpServer->errorString();
    //     // 强制关闭
    //     tcpServer->deleteLater();
    // }
    tcpServer->deleteLater();
    tcpServer = nullptr;
    // 4. 清理资源
    qDebug() << "Server stopped successfully";
}

void TcpServer::do_newConnection()
{
    if(!tcpServer->isListening()) {
        return;
    }
    while (tcpServer->hasPendingConnections()) {
        QTcpSocket* clientTcpSocket = tcpServer->nextPendingConnection();
        QString key = QString("%1:%2").arg(getCleanIp(clientTcpSocket->peerAddress())).arg(clientTcpSocket->peerPort());
        tcpSocketMap[key] = clientTcpSocket;
        QString str = QString("%1:%2: \n").arg(getCleanIp(clientTcpSocket->peerAddress())).arg(clientTcpSocket->peerPort());
        connect(clientTcpSocket, &QTcpSocket::connected, this, &TcpServer::do_connected);
        connect(clientTcpSocket, &QTcpSocket::readyRead, this, &TcpServer::do_readyRead);
        connect(clientTcpSocket, &QTcpSocket::disconnected, this, &TcpServer::do_disconnected);
        connect(clientTcpSocket, &QTcpSocket::destroyed, this, &TcpServer::do_destroyed);
        connect(clientTcpSocket, &QTcpSocket::errorOccurred, this, &TcpServer::do_errorOccurred);
    }
}

void TcpServer::do_connected()
{
    qDebug() << "client socket connected...";
    QTcpSocket* socket = qobject_cast<QTcpSocket*>(sender());
    QString key = QString("%1:%2").arg(getCleanIp(socket->peerAddress())).arg(socket->peerPort());
    emit custom_connected(key);
}

void TcpServer::do_readyRead()
{
    QTcpSocket* socket = qobject_cast<QTcpSocket*>(sender());
    QString key = QString("%1:%2").arg(getCleanIp(socket->peerAddress())).arg(socket->peerPort());
    QByteArray data = socket->readAll();
    // 自定义业务处理
    // ....暂时不处理，直接发送信号给外界
    emit custom_readyRead(key, data);
}

void TcpServer::do_disconnected()
{
    qDebug() << "tcp socket disconnected start...";
    QTcpSocket* socket = qobject_cast<QTcpSocket*>(sender());
    QString key = QString("%1:%2").arg(getCleanIp(socket->peerAddress())).arg(socket->peerPort());
    socket->deleteLater();
    tcpSocketMap.remove(key);
    qDebug() << "tcp socket disconnected end...";
    qDebug() << "tcp server  socket  connect close";
}

void TcpServer::do_destroyed()
{
    // 这个是对象被销毁时调用的最后调用的，不是tcpsocket的，是object对象的，一般不用这个信号
    qDebug() << "tcp socket  destroyed start... "  ;
    qDebug() << "tcp socket  destroyed end... "  ;
}

void TcpServer::do_errorOccurred(QAbstractSocket::SocketError error)
{
    qDebug() << "tcp socket errorOccurred start...";
    QTcpSocket* socket = qobject_cast<QTcpSocket*>(sender());
    qDebug() << "Socket error:" << error << socket->errorString();
    // 发送错误时 一般不删除对象，典型用途：处理网络错误（如连接拒绝、超时、远程关闭等） ,常见错误有
    // QAbstractSocket::ConnectionRefusedError（连接被拒绝）
    // QAbstractSocket::RemoteHostClosedError（远程主机关闭连接）
    // QAbstractSocket::SocketTimeoutError（操作超时）
    // socket->deleteLater();
    emit custom_errorOccurred(error);
    qDebug() << "tcp socket errorOccurred end...";
}

void TcpServer::do_write(const QString &msg)
{
    // 使用迭代器
    for (auto it = tcpSocketMap.begin(); it != tcpSocketMap.end(); ++it) {
        if(it.value()->state() == QAbstractSocket::ConnectedState) {
            it.value()->write( msg.toUtf8());
        } else {
            qWarning() << "Cannot send data - socket not connected";
        }
    }
}


QString TcpServer::getCleanIp(const QHostAddress &address)
{
    QString ip = address.toString();
    // 移除IPv6的方括号(如果有)
    ip.remove('[');
    ip.remove(']');
    // 转换IPv4映射的IPv6地址
    if(ip.startsWith("::ffff:")) {
        ip = ip.mid(7);
    }
    return ip;
}
